/*
 * SPDX-License-Identifier: GPL-2.0
 * Copyright (c) Huawei Technologies Co., Ltd. 2021-2023. All rights reserved.
 * Description:
 * Author: -
 * Create: 2021.4.19
 */

#include "ossl_knl.h"
#include "hiudk3.h"
#include "hiudk_internal.h"

/**
 * @brief bloom filter的id减少引用计数
 * @details bloom filter的id减少引用计数，减为0时发送API清零，此接口会休眠
 * @param udkdev 表征PF的设备指针
 * @param id id
 * @retval 0 成功
 * @retval -1 失败
 * @author
 * @date 2022-4-28
 */
s32 hiudk_cqm_bloomfilter_dec(void *udkdev, u16 func_id, u64 id)
{
    void *sdk_hwdev = NULL;
    struct hiudk_ops *ops = NULL;

    if (unlikely(!CHECK_UDK_DEV(udkdev))) {
        pr_err("udkdev is error! \n");
        return -EINVAL;
    }

    sdk_hwdev = GET_SDKHWDEV_FROM_HIUDKHWDEV(udkdev);
    ops = GET_SDKOPS_FROM_HIUDKHWDEV(udkdev);
    if (likely((ops != NULL) && (ops->cqm_ops.hiudk_cqm_bloomfilter_dec != NULL))) {
        return ops->cqm_ops.hiudk_cqm_bloomfilter_dec(sdk_hwdev, func_id, id);
    }
    pr_err("ops is NULL! \n");
    return -EINVAL;
}

EXPORT_SYMBOL(hiudk_cqm_bloomfilter_dec);

/**
 * @brief bloom filter的id增加引用计数
 * @details bloom filter的id增加引用计数，由0->1时发送API置位，此接口会休眠
 * @param udkdev 表征PF的设备指针
 * @param id id
 * @retval 0 成功
 * @retval -1 失败
 * @author
 * @date 2022-4-28
 */
s32 hiudk_cqm_bloomfilter_inc(void *udkdev, u16 func_id, u64 id)
{
    void *sdk_hwdev = NULL;
    struct hiudk_ops *ops = NULL;

    if (unlikely(!CHECK_UDK_DEV(udkdev))) {
        pr_err("udkdev is error! \n");
        return -EINVAL;
    }

    sdk_hwdev = GET_SDKHWDEV_FROM_HIUDKHWDEV(udkdev);
    ops = GET_SDKOPS_FROM_HIUDKHWDEV(udkdev);
    if (likely((ops != NULL) && (ops->cqm_ops.hiudk_cqm_bloomfilter_inc != NULL))) {
        return ops->cqm_ops.hiudk_cqm_bloomfilter_inc(sdk_hwdev, func_id, id);
    }
    pr_err("ops is NULL! \n");
    return -EINVAL;
}

EXPORT_SYMBOL(hiudk_cqm_bloomfilter_inc);

/**
 * @brief 申请一个cmd buffer
 * @details 申请一个cmd buffer，buffer大小固定2K，buffer内容没有清零，需要业务清零
 * @param udkdev 表征PF的设备指针
 * @retval cqm_cmd_buf_s 命令buffer指针
 * @author
 * @date 2022-4-28
 */
cqm_cmd_buf_s *hiudk_cqm_cmd_alloc(void *udkdev)
{
    void *sdk_hwdev = NULL;
    struct hiudk_ops *ops = NULL;

    if (unlikely(!CHECK_UDK_DEV(udkdev))) {
        pr_err("udkdev is error! \n");
        return NULL;
    }

    sdk_hwdev = GET_SDKHWDEV_FROM_HIUDKHWDEV(udkdev);
    ops = GET_SDKOPS_FROM_HIUDKHWDEV(udkdev);
    if (likely((ops != NULL) && (ops->cqm_ops.hiudk_cqm_cmd_alloc != NULL))) {
        return ops->cqm_ops.hiudk_cqm_cmd_alloc(sdk_hwdev);
    }
    pr_err("ops is NULL! \n");
    return NULL;
}

EXPORT_SYMBOL(hiudk_cqm_cmd_alloc);

/**
 * @brief 释放一个cmd buffer
 * @details 释放一个cmd buffer
 * @param udkdev 表征PF的设备指针
 * @param cmd_buf 待释放的cmd buffer指针
 * @retval void
 * @author
 * @date 2022-4-28
 */
void hiudk_cqm_cmd_free(void *udkdev, cqm_cmd_buf_s *cmd_buf)
{
    void *sdk_hwdev = NULL;
    struct hiudk_ops *ops = NULL;

    if (unlikely(!CHECK_UDK_DEV(udkdev))) {
        pr_err("udkdev is error! \n");
        return;
    }

    sdk_hwdev = GET_SDKHWDEV_FROM_HIUDKHWDEV(udkdev);
    ops = GET_SDKOPS_FROM_HIUDKHWDEV(udkdev);
    if (likely((ops != NULL) && (ops->cqm_ops.hiudk_cqm_cmd_free != NULL))) {
        ops->cqm_ops.hiudk_cqm_cmd_free(sdk_hwdev, cmd_buf);
        return;
    }
    pr_err("ops is NULL! \n");
    return;
}

EXPORT_SYMBOL(hiudk_cqm_cmd_free);

/**
 * @brief 业务驱动向CQM设置需要初始化的fake vf数量
 * @details 业务驱动向CQM设置需要初始化的fake vf数量
 * @param udkdev 表征PF的设备指针
 * @param fake_vf_num_cfg 需要初始化的fake vf数量
 * @retval 0 成功
 * @retval -1 失败
 * @author
 * @date 2022-2-10
 */
s32 hiudk_cqm_fake_vf_num_set(void *udkdev, u16 fake_vf_num_cfg)
{
    void *sdk_hwdev = NULL;
    struct hiudk_ops *ops = NULL;

    if (unlikely(!CHECK_UDK_DEV(udkdev))) {
        pr_err("udkdev is error! \n");
        return -EINVAL;
    }

    sdk_hwdev = GET_SDKHWDEV_FROM_HIUDKHWDEV(udkdev);
    ops = GET_SDKOPS_FROM_HIUDKHWDEV(udkdev);
    if (likely((ops != NULL) && (ops->cqm_ops.hiudk_cqm_fake_vf_num_set != NULL))) {
        return ops->cqm_ops.hiudk_cqm_fake_vf_num_set(sdk_hwdev, fake_vf_num_cfg);
    }
    pr_err("ops is NULL! \n");
    return -EINVAL;
}

EXPORT_SYMBOL(hiudk_cqm_fake_vf_num_set);

/**
 * @brief 清零hash buffer
 * @details 根据funtion id进行对应hash buffer 清零
 * @param udkdev 表征PF的设备指针
 * @param global_funcid
 * @retval void
 * @author
 * @date 2022-4-28
 */
void hiudk_cqm_function_hash_buf_clear(void *udkdev, s32 global_funcid)
{
    void *sdk_hwdev = NULL;
    struct hiudk_ops *ops = NULL;

    if (unlikely(!CHECK_UDK_DEV(udkdev))) {
        pr_err("udkdev is error! \n");
        return;
    }

    sdk_hwdev = GET_SDKHWDEV_FROM_HIUDKHWDEV(udkdev);
    ops = GET_SDKOPS_FROM_HIUDKHWDEV(udkdev);
    if (likely((ops != NULL) && (ops->cqm_ops.hiudk_cqm_function_hash_buf_clear != NULL))) {
        ops->cqm_ops.hiudk_cqm_function_hash_buf_clear(sdk_hwdev, global_funcid);
        return;
    }
    pr_err("ops is NULL! \n");
    return;
}

EXPORT_SYMBOL(hiudk_cqm_function_hash_buf_clear);

/**
 * @brief 清零timer buffer
 * @details 根据funtion id进行对应timer buffer 清零。要求funtion id从0开始计算，且timer buffer按funtion id依次排列
 * @param udkdev 表征PF的设备指针
 * @param function_id funtion id
 * @retval void
 * @author
 * @date 2022-4-28
 */
void hiudk_cqm_function_timer_clear(void *udkdev, u32 function_id)
{
    void *sdk_hwdev = NULL;
    struct hiudk_ops *ops = NULL;

    if (unlikely(!CHECK_UDK_DEV(udkdev))) {
        pr_err("udkdev is error! \n");
        return;
    }

    sdk_hwdev = GET_SDKHWDEV_FROM_HIUDKHWDEV(udkdev);
    ops = GET_SDKOPS_FROM_HIUDKHWDEV(udkdev);
    if (likely((ops != NULL) && (ops->cqm_ops.hiudk_cqm_function_timer_clear != NULL))) {
        ops->cqm_ops.hiudk_cqm_function_timer_clear(sdk_hwdev, function_id);
        return;
    }
    pr_err("ops is NULL! \n");
    return;
}

EXPORT_SYMBOL(hiudk_cqm_function_timer_clear);

void *hiudk_cqm_get_db_addr(void *udkdev, u32 service_type)
{
    void *sdk_hwdev = NULL;
    struct hiudk_ops *ops = NULL;

    if (unlikely(!CHECK_UDK_DEV(udkdev))) {
        pr_err("udkdev is error! \n");
        return NULL;
    }

    sdk_hwdev = GET_SDKHWDEV_FROM_HIUDKHWDEV(udkdev);
    ops = GET_SDKOPS_FROM_HIUDKHWDEV(udkdev);
    if (likely((ops != NULL) && (ops->cqm_ops.hiudk_cqm_get_db_addr != NULL))) {
        return ops->cqm_ops.hiudk_cqm_get_db_addr(sdk_hwdev, service_type);
    }
    pr_err("ops is NULL! \n");
    return NULL;
}

EXPORT_SYMBOL(hiudk_cqm_get_db_addr);

s32 hiudk_cqm_get_hardware_db_addr(void *udkdev, u64 *addr, u32 service_type)
{
    void *sdk_hwdev = NULL;
    struct hiudk_ops *ops = NULL;

    if (unlikely(!CHECK_UDK_DEV(udkdev))) {
        pr_err("udkdev is error! \n");
        return -EINVAL;
    }

    sdk_hwdev = GET_SDKHWDEV_FROM_HIUDKHWDEV(udkdev);
    ops = GET_SDKOPS_FROM_HIUDKHWDEV(udkdev);
    if (likely((ops != NULL) && (ops->cqm_ops.hiudk_cqm_get_hardware_db_addr != NULL))) {
        return ops->cqm_ops.hiudk_cqm_get_hardware_db_addr(sdk_hwdev, addr, service_type);
    }
    pr_err("ops is NULL! \n");
    return -EINVAL;
}

EXPORT_SYMBOL(hiudk_cqm_get_hardware_db_addr);

/**
 * @brief box方式发送一个cmd，开放cos_id, 该接口会挂完成量，造成休眠
 * @details box方式发送一个cmd，该接口会挂完成量，造成休眠
 * @param udkdev 表征PF的设备指针
 * @param mod 发送cmd的模块
 * @param cmd 命令字
 * @param cos_id
 * @param buf_in 输入命令buffer
 * @param buf_out 返回命令buffer
 * @param out_param 命令返回的inline data出参
 * @param timeout 命令超时时间，单位ms
 * @param channel 调用者channel id
 * @retval 0 成功
 * @retval !=0 失败
 * @author
 * @date 2020-4-11
 */
s32 hiudk_cqm_lb_send_cmd_box(void *udkdev, u8 mod, u8 cmd, u8 cos_id, cqm_cmd_buf_s *buf_in, cqm_cmd_buf_s *buf_out,
    u64 *out_param, u32 timeout, u16 channel)
{
    void *sdk_hwdev = NULL;
    struct hiudk_ops *ops = NULL;

    if (unlikely(!CHECK_UDK_DEV(udkdev))) {
        pr_err("udkdev is error! \n");
        return -EINVAL;
    }

    sdk_hwdev = GET_SDKHWDEV_FROM_HIUDKHWDEV(udkdev);
    ops = GET_SDKOPS_FROM_HIUDKHWDEV(udkdev);
    if (likely((ops != NULL) && (ops->cqm_ops.hiudk_cqm_lb_send_cmd_box != NULL))) {
        return ops->cqm_ops.hiudk_cqm_lb_send_cmd_box(sdk_hwdev, mod, cmd, cos_id, buf_in, buf_out, out_param, timeout,
            channel);
    }
    pr_err("ops is NULL! \n");
    return -EINVAL;
}

EXPORT_SYMBOL(hiudk_cqm_lb_send_cmd_box);

/**
 * @brief box方式发送一个cmd，开放cos_id, 该接口直接返回
 * @details box方式发送一个cmd，该接口直接返回
 * @param udkdev 表征PF的设备指针
 * @param mod 发送cmd的模块
 * @param cmd 命令字
 * @param cos_id
 * @param buf_in 输入命令buffer
 * @param channel 调用者channel id
 * @retval 0 成功
 * @retval !=0 失败
 * @author
 * @date 2023-5-19
 */
s32 hiudk_cqm_lb_send_cmd_box_async(void *udkdev, u8 mod, u8 cmd, u8 cos_id,
    cqm_cmd_buf_s *buf_in, u16 channel)
{
    void *sdk_hwdev = NULL;
    struct hiudk_ops *ops = NULL;

    if (unlikely(!CHECK_UDK_DEV(udkdev))) {
        pr_err("udkdev is error! \n");
        return -EINVAL;
    }

    sdk_hwdev = GET_SDKHWDEV_FROM_HIUDKHWDEV(udkdev);
    ops = GET_SDKOPS_FROM_HIUDKHWDEV(udkdev);
    if (likely((ops != NULL) && (ops->cqm_ops.hiudk_cqm_lb_send_cmd_box_async != NULL))) {
        return ops->cqm_ops.hiudk_cqm_lb_send_cmd_box_async(sdk_hwdev, mod, cmd, cos_id, buf_in, channel);
    }
    pr_err("ops is NULL! \n");
    return -EINVAL;
}

EXPORT_SYMBOL(hiudk_cqm_lb_send_cmd_box_async);

s32 hiudk_cqm_ring_direct_wqe_db(void *udkdev, u32 service_type, u8 db_count, void *direct_wqe)
{
    void *sdk_hwdev = NULL;
    struct hiudk_ops *ops = NULL;

    if (unlikely(!CHECK_UDK_DEV(udkdev))) {
        pr_err("udkdev is error! \n");
        return -EINVAL;
    }

    sdk_hwdev = GET_SDKHWDEV_FROM_HIUDKHWDEV(udkdev);
    ops = GET_SDKOPS_FROM_HIUDKHWDEV(udkdev);
    if (likely((ops != NULL) && (ops->cqm_ops.hiudk_cqm_ring_direct_wqe_db != NULL))) {
        return ops->cqm_ops.hiudk_cqm_ring_direct_wqe_db(sdk_hwdev, service_type, db_count, direct_wqe);
    }
    pr_err("ops is NULL! \n");
    return -EINVAL;
}

EXPORT_SYMBOL(hiudk_cqm_ring_direct_wqe_db);

/**
 * @brief 敲硬件doorbell
 * @details 敲硬件doorbell
 * @param udkdev 表征PF的设备指针
 * @param service_type 每种内核态业务会分配一页硬件doorbell page
 * @param db_count doorbell中超出64b的PI[7:0]
 * @param db doorbell内容，由业务组织，如存在大小端转换，需要业务完成
 * @retval 0 成功
 * @retval -1 失败
 * @author
 * @date 2022-4-28
 */
s32 hiudk_cqm_ring_hardware_db(void *udkdev, u32 service_type, u8 db_count, u64 db)
{
    void *sdk_hwdev = NULL;
    struct hiudk_ops *ops = NULL;

    if (unlikely(!CHECK_UDK_DEV(udkdev))) {
        pr_err("udkdev is error! \n");
        return -EINVAL;
    }

    sdk_hwdev = GET_SDKHWDEV_FROM_HIUDKHWDEV(udkdev);
    ops = GET_SDKOPS_FROM_HIUDKHWDEV(udkdev);
    if (likely((ops != NULL) && (ops->cqm_ops.hiudk_cqm_ring_hardware_db != NULL))) {
        return ops->cqm_ops.hiudk_cqm_ring_hardware_db(sdk_hwdev, service_type, db_count, db);
    }
    pr_err("ops is NULL! \n");
    return -EINVAL;
}

EXPORT_SYMBOL(hiudk_cqm_ring_hardware_db);

/**
 * @brief 敲软件doorbell
 * @details 敲软件doorbell
 * @param object 对象指针
 * @param db_record 软件doorbell内容，如存在大小端转换，需要业务完成
 * @retval 0 成功
 * @retval -1 失败
 * @author
 * @date 2022-4-28
 */
s32 hiudk_cqm_ring_software_db(void *udkdev, cqm_object_s *object, u64 db_record)
{
    struct hiudk_ops *ops = NULL;

    if (unlikely(object == NULL)) {
        pr_err("object is NULL! \n");
        return -EINVAL;
    }

    ops = GET_SDKOPS_FROM_HIUDKHWDEV(udkdev);
    if (likely((ops != NULL) && (ops->cqm_ops.hiudk_cqm_ring_software_db != NULL))) {
        return ops->cqm_ops.hiudk_cqm_ring_software_db(object, db_record);
    }
    pr_err("ops is NULL! \n");
    return -EINVAL;
}

EXPORT_SYMBOL(hiudk_cqm_ring_software_db);

/**
 * @brief box方式发送一个cmd，该接口会挂完成量，造成休眠
 * @details box方式发送一个cmd，该接口会挂完成量，造成休眠
 * @param udkdev 表征PF的设备指针
 * @param mod 发送cmd的模块
 * @param cmd 命令字
 * @param buf_in 输入命令buffer
 * @param buf_out 返回命令buffer
 * @param out_param 命令返回的inline data出参
 * @param timeout 命令超时时间，单位ms
 * @param channel 调用者channel id
 * @retval 0 成功
 * @retval !=0 失败
 * @author
 * @date 2022-4-28
 */
s32 hiudk_cqm_send_cmd_box(void *udkdev, u8 mod, u8 cmd, cqm_cmd_buf_s *buf_in, cqm_cmd_buf_s *buf_out, u64 *out_param,
    u32 timeout, u16 channel)
{
    void *sdk_hwdev = NULL;
    struct hiudk_ops *ops = NULL;

    if (unlikely(!CHECK_UDK_DEV(udkdev))) {
        pr_err("udkdev is error! \n");
        return -EINVAL;
    }

    sdk_hwdev = GET_SDKHWDEV_FROM_HIUDKHWDEV(udkdev);
    ops = GET_SDKOPS_FROM_HIUDKHWDEV(udkdev);
    if (likely((ops != NULL) && (ops->cqm_ops.hiudk_cqm_send_cmd_box != NULL))) {
        return ops->cqm_ops.hiudk_cqm_send_cmd_box(sdk_hwdev, mod, cmd, buf_in, buf_out, out_param, timeout, channel);
    }
    pr_err("ops is NULL! \n");
    return -EINVAL;
}

EXPORT_SYMBOL(hiudk_cqm_send_cmd_box);

/**
 * @brief imm方式发送一个cmd，该接口会挂完成量，造成休眠
 * @details imm方式发送一个cmd，该接口会挂完成量，造成休眠
 * @param udkdev 表征PF的设备指针
 * @param mod 发送cmd的模块
 * @param cmd 命令字
 * @param buf_in 输入命令buffer
 * @param out_param 返回命令buffer
 * @param timeout 命令超时时间，单位ms
 * @param channel 调用者channel id
 * @retval 0 成功
 * @retval !=0 失败
 * @author
 * @date 2022-4-28
 */
s32 hiudk_cqm_send_cmd_imm(void *udkdev, u8 mod, u8 cmd, cqm_cmd_buf_s *buf_in, u64 *out_param, u32 timeout,
    u16 channel)
{
    void *sdk_hwdev = NULL;
    struct hiudk_ops *ops = NULL;

    if (unlikely(!CHECK_UDK_DEV(udkdev))) {
        pr_err("udkdev is error! \n");
        return -EINVAL;
    }

    sdk_hwdev = GET_SDKHWDEV_FROM_HIUDKHWDEV(udkdev);
    ops = GET_SDKOPS_FROM_HIUDKHWDEV(udkdev);
    if (likely((ops != NULL) && (ops->cqm_ops.hiudk_cqm_send_cmd_imm != NULL))) {
        return ops->cqm_ops.hiudk_cqm_send_cmd_imm(sdk_hwdev, mod, cmd, buf_in, out_param, timeout, channel);
    }
    pr_err("ops is NULL! \n");
    return -EINVAL;
}

EXPORT_SYMBOL(hiudk_cqm_send_cmd_imm);

/**
 * @brief 业务驱动向CQM注册回调模板
 * @details 业务驱动向CQM注册回调模板
 * @param udkdev 表征PF的设备指针
 * @param service_template 服务注册模板
 * @retval 0 成功
 * @retval -1 失败
 * @author
 * @date 2022-4-28
 */
s32 hiudk_cqm_service_register(void *udkdev, service_register_template_s *service_template)
{
    void *sdk_hwdev = NULL;
    struct hiudk_ops *ops = NULL;

    if (unlikely(!CHECK_UDK_DEV(udkdev))) {
        pr_err("udkdev is error! \n");
        return -EINVAL;
    }

    sdk_hwdev = GET_SDKHWDEV_FROM_HIUDKHWDEV(udkdev);
    ops = GET_SDKOPS_FROM_HIUDKHWDEV(udkdev);
    if (likely((ops != NULL) && (ops->cqm_ops.hiudk_cqm_service_register != NULL))) {
        return ops->cqm_ops.hiudk_cqm_service_register(sdk_hwdev, service_template);
    }
    pr_err("ops is NULL! \n");
    return -EINVAL;
}

EXPORT_SYMBOL(hiudk_cqm_service_register);

/**
 * @brief 业务驱动向CQM注销
 * @details 业务驱动向CQM注销
 * @param udkdev 表征PF的设备指针
 * @param service_type 服务类型
 * @retval void
 * @author
 * @date 2022-4-28
 */
void hiudk_cqm_service_unregister(void *udkdev, u32 service_type)
{
    void *sdk_hwdev = NULL;
    struct hiudk_ops *ops = NULL;

    if (unlikely(!CHECK_UDK_DEV(udkdev))) {
        pr_err("udkdev is error! \n");
        return;
    }

    sdk_hwdev = GET_SDKHWDEV_FROM_HIUDKHWDEV(udkdev);
    ops = GET_SDKOPS_FROM_HIUDKHWDEV(udkdev);
    if (likely((ops != NULL) && (ops->cqm_ops.hiudk_cqm_service_unregister != NULL))) {
        ops->cqm_ops.hiudk_cqm_service_unregister(sdk_hwdev, service_type);
        return;
    }
    pr_err("ops is NULL! \n");
    return;
}

EXPORT_SYMBOL(hiudk_cqm_service_unregister);

/**
 * @brief 释放container
 * @details 释放container
 * @param object 对象指针
 * @param container 要释放的container指针
 * @retval void
 * @author
 * @date 2022-4-28
 */
void hiudk_cqm_srq_used_rq_container_delete(void *udkdev, cqm_object_s *object, u8 *container)
{
    struct hiudk_ops *ops = NULL;

    if (unlikely(!CHECK_UDK_DEV(udkdev))) {
        pr_err("udkdev is error! \n");
        return;
    }

    ops = GET_SDKOPS_FROM_HIUDKHWDEV(udkdev);
    if (likely((ops != NULL) && (ops->cqm_ops.hiudk_cqm_srq_used_rq_container_delete != NULL))) {
        ops->cqm_ops.hiudk_cqm_srq_used_rq_container_delete(object, container);
        return;
    }
    pr_err("ops is NULL! \n");
    return;
}

EXPORT_SYMBOL(hiudk_cqm_srq_used_rq_container_delete);

/**
 * @brief 获取Timer的base虚拟地址
 * @details 获取Timer的base虚拟地址
 * @param udkdev 表征PF的设备指针
 * @retval void *Timer的base虚拟地址
 * @author
 * @date 2020-5-21
 */
void *hiudk_cqm_timer_base(void *udkdev)
{
    void *sdk_hwdev = NULL;
    struct hiudk_ops *ops = NULL;

    if (unlikely(!CHECK_UDK_DEV(udkdev))) {
        pr_err("udkdev is error! \n");
        return NULL;
    }

    sdk_hwdev = GET_SDKHWDEV_FROM_HIUDKHWDEV(udkdev);
    ops = GET_SDKOPS_FROM_HIUDKHWDEV(udkdev);
    if (likely((ops != NULL) && (ops->cqm_ops.hiudk_cqm_timer_base != NULL))) {
        return ops->cqm_ops.hiudk_cqm_timer_base(sdk_hwdev);
    }
    pr_err("ops is NULL! \n");
    return NULL;
}

EXPORT_SYMBOL(hiudk_cqm_timer_base);

s32 hiudk_cqm_dtoe_share_recv_queue_create(void *udkdev, u32 csize, u32 *cnt, u32 *idx)
{
    void *sdk_hwdev = NULL;
    struct hiudk_ops *ops = NULL;

    if (unlikely(!CHECK_UDK_DEV(udkdev))) {
        pr_err("udkdev is error! \n");
        return -EINVAL;
    }

    sdk_hwdev = GET_SDKHWDEV_FROM_HIUDKHWDEV(udkdev);
    ops = GET_SDKOPS_FROM_HIUDKHWDEV(udkdev);
    if (likely((ops != NULL) && (ops->cqm_ops.hiudk_cqm_dtoe_share_recv_queue_create != NULL))) {
        return ops->cqm_ops.hiudk_cqm_dtoe_share_recv_queue_create(sdk_hwdev, csize, cnt, idx);
    }
    pr_err("ops is NULL! \n");
    return -EINVAL;
}

EXPORT_SYMBOL(hiudk_cqm_dtoe_share_recv_queue_create);

void hiudk_cqm_dtoe_free_srq_bitmap_index(void *udkdev, u32 index_count, u32 index)
{
    void *sdk_hwdev = NULL;
    struct hiudk_ops *ops = NULL;

    if (unlikely(!CHECK_UDK_DEV(udkdev))) {
        pr_err("udkdev is error! \n");
        return;
    }

    sdk_hwdev = GET_SDKHWDEV_FROM_HIUDKHWDEV(udkdev);
    ops = GET_SDKOPS_FROM_HIUDKHWDEV(udkdev);
    if (likely((ops != NULL) && (ops->cqm_ops.hiudk_cqm_dtoe_free_srq_bitmap_index != NULL))) {
        ops->cqm_ops.hiudk_cqm_dtoe_free_srq_bitmap_index(sdk_hwdev, index_count, index);
        return;
    }
    pr_err("ops is NULL! \n");
    return;
}

EXPORT_SYMBOL(hiudk_cqm_dtoe_free_srq_bitmap_index);
